﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.Contracts;

namespace OpenLS.Spreadsheet
{
    class CellCluster: IEnumerable<Cell>
    {
        private readonly CellClusterKey _key;

        public CellCluster(CellClusterKey key)
        {
            _key = key;
        }
        public override string ToString()
        {
            return _key.ToString();
        }

        readonly List<Cell> _cells = new List<Cell>();

        public int Count
        {
            get { return _cells.Count; }
        }

        public void Remove(Cell cell)
        {
            Contract.Requires(cell != null);
            //\\should be here? Contract.Requires(_cells.Contains(cell));
            Contract.Requires(cell.State == Cell.CellState.Promoted);
            Contract.Ensures(!_cells.Contains (cell));
            Contract.Assert(_key.RangeAddress.Intersects(cell.GetRangeAddress()));
            _cells.Remove(cell);
        }

        internal void Add(Cell cell)
        {
            Contract.Requires(cell != null);
            Contract.Requires(!Contains(cell));
            Contract.Requires(cell.State == Cell.CellState.Promoted);
            Contract.Ensures(_cells.Contains(cell));

            // SJE on 11-07
            var canAddCell = (!_cells.Contains(cell)) && (!Enumerable.Any(_cells, c => c.Address == cell.Address));
            if (!canAddCell) return;
            // Contract.Assert(!_cells.Contains(cell));
            // Contract.Assert(!Enumerable.Any(_cells, c => c.Address == cell.Address));
            _cells.Add(cell);
        }

        public IEnumerator<Cell> GetEnumerator()
        {
            return _cells.GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }

        public bool Contains(Cell cell)
        {
            return _cells.Contains(cell);
        }
    }
}